#ifndef _INCLUDE_SETTINGS_H_
#define _INCLUDE_SETTINGS_H_
//=======================================================================//
//= Include files.													    =//
//=======================================================================//
#include <wx/arrstr.h>
#include <wx/filename.h>
#include <wx/string.h>
#include <wx/colour.h>
#include <wx/xml/xml.h>
#include <wx/wxcrt.h>
#include <wx/font.h>
#include "Encoder.h"

//=======================================================================//
//= Marco declare.                                                      =//
//=======================================================================//
#define	INVLIAD_SETTING_ITEM_INDEX			(-1)

#define GlobalEncorderSettings()			(ConfigurationInstance().EncoderConfiguration())
#define GlobalPreviewSettings()				(ConfigurationInstance().PanelConfiguration())
#define GlobalOutputSettings()				(ConfigurationInstance().OutputConfiguration())
#define GlobalPaintFont()					(WorkSettingsInstance().PaintFont())

// For XML data analyze.
#define CFG_XML_NODE_NAME_CFG_ROOT			(wxT("SimplePixelTools"))
#define CFG_XML_NODE_NAME_PREVIEWPANEL		(wxT("PreviewPanel"))
#define CFG_XML_NODE_NAME_PIXEL_SIZE		(wxT("PixelSize"))
#define CFG_XML_NODE_NAME_PIXEL_COLOR		(wxT("Color"))
#define CFG_XML_NODE_NAME_OUTPUT			(wxT("Output"))
#define CFG_XML_NODE_NAME_OUTPUT_COMMENT	(wxT("Comment"))
#define CFG_XML_NODE_NAME_OUTPUT_DATA		(wxT("Data"))


#define CFG_XML_NODE_NAME_START_ROOT		(wxT("SimplePixelTools-Startup"))
// For XML output.
#define CGF_XML_BOOL_AS_STR(B)				((B)?wxT("true"):wxT("false"))
#define CGF_XML_STR_AS_BOOL(STR)			((STR).IsSameAs(wxT("true"), false))

//=======================================================================//
//= Data type definition.                                               =//
//=======================================================================//
typedef enum
{
	NO_COMMENT,
	BEFORE_CODE,
	AFTER_CODE
}COMMENT_TYPE;

//=======================================================================//
//= Global variable declare.                                            =//
//=======================================================================//
extern const wxString			CommentItems[];
extern const size_t				COMMENT_ITEMS_COUNT;

//=======================================================================//
//= Class declare.                                                      =//
//=======================================================================//
class PanelConfiguration
{
private:
	wxColour					m_clsForeground;
	wxColour					m_clsBackground;
	wxColour					m_clsGridround;
	wxSize						m_clsPixelSize;

public:
								PanelConfiguration(void);
								PanelConfiguration(const wxXmlNode* pclsXmlNode);
								PanelConfiguration(const PanelConfiguration& clsSource);
	const wxColour&				GetForegroundColour(void) const 			{return m_clsForeground;}
	const wxColour&				GetBackgroundColour(void) const 			{return m_clsBackground;}
	const wxColour&				GetGridColour(void) const					{return m_clsGridround;}
	const wxSize&				PixelUnitSize(void) const					{return m_clsPixelSize;}
	void						SetForegroundColour(const wxColour& clsNewForegroundColor){m_clsForeground = clsNewForegroundColor;}
	void						SetBackgroundColour(const wxColour& clsNewBackgroundColor){m_clsBackground = clsNewBackgroundColor;}
	void						SetGridColour(const wxColour& clsNewGridColor){m_clsGridround = clsNewGridColor;}
	void						SetPixelUnitSize(const wxSize& clsNewPixelUnitSize){m_clsPixelSize = clsNewPixelUnitSize;}
	void						SetPixelUnitSize(int iNewWidth, int iNewHeight){m_clsPixelSize.SetWidth(iNewWidth); m_clsPixelSize.SetHeight(iNewHeight);}
	void						SetPixelUnitWidth(int iNewWidth)			{m_clsPixelSize.SetWidth(iNewWidth);}
	void						SetPixelUnitHeight(int iNewHeight)			{m_clsPixelSize.SetHeight(iNewHeight);}
	PanelConfiguration&			operator=(const PanelConfiguration& clsObject);
	wxXmlNode*					CreateXmlNode(void);
	bool						FromXmlNode(const wxXmlNode* pclsXmlNode);
};

class OutputConfiguration
{
private:
	COMMENT_TYPE				m_eCommentType;
	bool						m_bNewLine;
	int							m_iNumInLine;
public:
								OutputConfiguration(void);
								OutputConfiguration(const wxXmlNode* pclsXmlNode);
								OutputConfiguration(const OutputConfiguration& clsSource);
	wxXmlNode*					CreateXmlNode(void);
	bool						FromXmlNode(const wxXmlNode* pclsXmlNode);
	COMMENT_TYPE				GetCommentType(void) const					{return m_eCommentType;}
	bool						GetCommentInNewline(void) const				{return m_bNewLine;}
	int							GetNumInLine(void) const					{return m_iNumInLine;}
	void						SetCommentType(COMMENT_TYPE eNewCommentType){m_eCommentType = eNewCommentType;}
	void						SetCommentInNewline(bool bCommentInNewLine)	{m_bNewLine = bCommentInNewLine;}
	void						SetNumInline(int iNumInLine)				{m_iNumInLine = iNumInLine;}
	OutputConfiguration&		operator=(const OutputConfiguration& clsObject);
};

class GlobalConfiguration
{
private:
	PanelConfiguration			m_clsPerviewCfg;
	EncoderConfiguration		m_clsEncoderCfg;
	OutputConfiguration			m_clsOutputCfg;

public:
								GlobalConfiguration(void);
								GlobalConfiguration(const wxString& cstrFilePath);
								GlobalConfiguration(const GlobalConfiguration& clsSource);
	void						CopyTo(GlobalConfiguration& clsDest) const;
	bool						Load(const wxString& cstrFilePath);
	bool						Save(const wxString& cstrFilePath);
	PanelConfiguration&			PanelConfiguration(void)					{return m_clsPerviewCfg;}
	EncoderConfiguration&		EncoderConfiguration(void)					{return m_clsEncoderCfg;}
	OutputConfiguration&		OutputConfiguration(void)					{return m_clsOutputCfg;}
	GlobalConfiguration&		operator=(const GlobalConfiguration& clsObject);
};

class ExtendedFontSettings
{
private:
	bool					m_bForceWidth;
	int						m_iForcedWidth;
	bool					m_bCutout;
	int						m_iCutoutHeight;
	int						m_iOffsetX;
	int						m_iOffsetY;

public:
							ExtendedFontSettings(void);
							ExtendedFontSettings(const ExtendedFontSettings& clsSource);
							ExtendedFontSettings(const wxXmlNode* pclsXmlNode);
	void					SetToDefault(void);
	bool					IsForceWidth(void) const				{return m_bForceWidth;}
	void					SetForceWidth(bool bForceWidth)			{m_bForceWidth = bForceWidth;}
	int						GetForcedWidthValue(void) const			{return m_iForcedWidth;}
	void					SetForcedWidthValue(int iForcedWidth)	{m_iForcedWidth = iForcedWidth;}
    bool					IsCutoutEnable(void) const				{return m_bCutout;}
    void					EnableCutout(bool bEnable)				{m_bCutout = bEnable;}
    void					SetCutoutHeight(int iHeight)			{m_iCutoutHeight = iHeight;}
    int						GetCutoutHeight(void) const				{return m_iCutoutHeight;}
    int						GetOffsetX(void) const					{return m_iOffsetX;}
	int						GetOffsetY(void) const					{return m_iOffsetY;}
	void					SetOffsetX(int iOffsetX)				{m_iOffsetX = iOffsetX;}
	void					SetOffsetY(int iOffsetY)				{m_iOffsetY = iOffsetY;}
	void					IncOffsetX(void)						{++m_iOffsetX;}
	void					IncOffsetY(void)						{++m_iOffsetY;}
	void					DecOffsetX(void)						{--m_iOffsetX;}
	void					DecOffsetY(void)						{--m_iOffsetY;}
	bool					LoadFromXML(const wxXmlNode* pclsXmlNode);
	wxXmlNode*				ExportToXML(void);
};

class FontSettings
{
private:
	wxFont					m_clsGeneralFontInfo;
	ExtendedFontSettings	m_clsExtendedFontInfo;

public:
							FontSettings(const wxString& strFontName = wxEmptyString);
							FontSettings(const FontSettings& clsObject);
	virtual FontSettings*	Clone(void)	const						{return new FontSettings(*this);}
	void					SetName(const wxString& cstrFaceName)	{m_clsGeneralFontInfo.SetFaceName(cstrFaceName);}
	wxString				GetName(void)							{return m_clsGeneralFontInfo.GetFaceName();}
	void					SetFont(const FontSettings& clsObject);
	void					SetFont(const wxFont& clsObject);
	void					SetSize(int iFontSize);
	int						GetSize(void) const 					{return m_clsGeneralFontInfo.GetPixelSize().GetHeight();}
	int						GetHeight(void) const;
	bool 					IsBold(void) const;
	void					SetBold(bool bBold);
	bool					IsItalic(void) const;
	void					SetItalic(bool bTialic);
	const wxFont&			Font(void) const						{return m_clsGeneralFontInfo;}
	const ExtendedFontSettings& ExtendedInfo(void) const			{return m_clsExtendedFontInfo;}
	bool					LoadFromXML(const wxXmlNode* pclsXmlNode);
	wxXmlNode*				ExportToXML(void);
	FontSettings&			operator=(const FontSettings& clsObject);
	FontSettings&			operator=(const wxFont& clsObject);
	bool					IsForceWidth(void) const				{return m_clsExtendedFontInfo.IsForceWidth();}
	void					SetForceWidth(bool bForceWidth)			{m_clsExtendedFontInfo.SetForceWidth(bForceWidth);}
	int						GetForcedWidthValue(void) const			{return m_clsExtendedFontInfo.GetForcedWidthValue();}
	void					SetForcedWidthValue(int iForcedWidth)	{m_clsExtendedFontInfo.SetForcedWidthValue(iForcedWidth);}
    bool					IsCutoutEnable(void) const				{return m_clsExtendedFontInfo.IsCutoutEnable();}
    void					EnableCutout(bool bEnable)				{m_clsExtendedFontInfo.EnableCutout(bEnable);}
    void					SetCutoutHeight(int iHeight)			{m_clsExtendedFontInfo.SetCutoutHeight(iHeight);}
    int						GetCutoutHeight(void) const				{return m_clsExtendedFontInfo.GetCutoutHeight();}
    int						GetOffsetX(void) const					{return m_clsExtendedFontInfo.GetOffsetX();}
	int						GetOffsetY(void) const					{return m_clsExtendedFontInfo.GetOffsetY();}
	void					SetOffsetX(int iOffsetX)				{m_clsExtendedFontInfo.SetOffsetX(iOffsetX);}
	void					SetOffsetY(int iOffsetY)				{m_clsExtendedFontInfo.SetOffsetY(iOffsetY);}
	void					IncOffsetX(void)						{m_clsExtendedFontInfo.IncOffsetX();}
	void					IncOffsetY(void)						{m_clsExtendedFontInfo.IncOffsetY();}
	void					DecOffsetX(void)						{m_clsExtendedFontInfo.DecOffsetX();}
	void					DecOffsetY(void)						{m_clsExtendedFontInfo.DecOffsetY();}
};

class WorkSettings
{
private:
	FontSettings				m_clsPaintFont;

public:
								WorkSettings(void);
								WorkSettings(const wxString& cstrFilePath);
								WorkSettings(const WorkSettings& clsSource);
	void						CopyTo(WorkSettings& clsDest) const;
	bool						Load(const wxString& cstrFilePath);
	bool						Save(const wxString& cstrFilePath);
	FontSettings&				PaintFont(void) 							{return m_clsPaintFont;}
	WorkSettings&				operator=(const WorkSettings& clsObject);
};

//=======================================================================//
//= Function declare.                                                   =//
//=======================================================================//
GlobalConfiguration&			ConfigurationInstance(void);
WorkSettings&					WorkSettingsInstance(void);


#endif // _INCLUDE_SETTINGS_H_
